-- UIMopUp
-- Created by huanghr May/18/2015
-- 扫荡统计界面

UIMopUp = class("UIMopTop", function()
    return cc.Layer:create();
end);

function UIMopUp.create(args, exp, level, areaId)
    return UIMopUp.new(args, exp, level, areaId);
end

--
local STAT_STATE_TITLE_ANIMA   =    1;   -- 标题动画
local STAT_STATE_SCORE_ANIM    =    2;   -- 金币和经验滚动
local STAT_STATE_GROUP_ANIM    =    3;   -- 物品飞入
local STAT_STATE_END           =    4;   -- 结束状态

-- 加速因子
local accelarateFactor = 1;

-- 每页停留时间
local waitingTime = 1;

-- 第一组和第二组数据飞入时间
local textDuration = 0.3;

function UIMopUp:ctor(args, exp, level, areaId)
    -- 初始化
    self:setName("UIMopUp");
    local node = cc.CSLoader:createNode("layout/combat_stat/CombatStat.csb");
    self:addChild(node);
    self.node = node;
    self.dungeonId = areaId;

    -- 扫荡前经验和等级
    self.oldExp = exp;
    self.oldLevel = level;
    self.oldMaxExp = UserM.queryWorldTree(self.oldLevel, "exp");

    -- 立即显示的标记
    self.flog = false;
    self.itemsflog = false;
    self.isLastAnimation = false;
    self.isDoingExpAnimation = false;

    self:setLocalZOrder(UIMgr.BONUS_NOTIFY_ZORDER + 1);

    -- 扫荡信息
    self.bonus = args;

    -- 注册点击事件
    self:registerTouchEvent();

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 重绘
    self:redraw();

    -- 初始化
    self:init(args);

    -- 延迟开始动画效果
    local delay = 0.1;

    local function callback()
        self:start();
    end
    performWithDelay(self, callback, delay);

    -- 适配
    self:resize();
end

-- 适配
function UIMopUp:resize()
    local node = self.node;
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "black_bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- top_bg置于顶部
    AlignM.alignToTopCenter(node, "top_bg");
    AlignM.alignToTopCenter(node, "TOP");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
    AlignM.alignToBottomCenter(node, "bottom_bg");

    -- TOP置顶并缩放至合适大小
    local TOP = node:getChildByName("TOP");
    local scale = math.max(w / DESIGN_WIDTH, h / DESIGN_HEIGHT);

    local topBg = findChildByName(node, "top_bg");
    local bottomBg = findChildByName(node, "bottom_bg");
    local newWidth = w * DESIGN_HEIGHT / h;

    -- 上下底图的大小为640所以这么处理
    if h / w < 1.5 then
        topBg:setScaleX(768/DESIGN_WIDTH * topBg:getScale());
        bottomBg:setScaleX(768/DESIGN_WIDTH * bottomBg:getScale());
        scale = 768/DESIGN_WIDTH * bottomBg:getScaleX();
    end

    bottomBg:setPosition(w/2, -40 * scale);
end

-- 重绘
function UIMopUp:redraw()
    local node = self.node;

    local formTitleLabel = findChildByName(node, "TOP/title_node/title");
    formTitleLabel:setString(getLocStr("mop_up_succ_title"));
    TextStyleM.setArtWordTitleStyle(formTitleLabel);

    -- TOP/BOTTOM背景
    local topBg = findChildByName(node, "top_bg");
    local bottomBg = findChildByName(node, "bottom_bg");

    -- 根据地图区域获取风格
    local dungeonId = self.dungeonId
        or ME.user.dbase:query("currentDungeon") or DungeonM.getDungeonId();

    local parentId;
    if dungeonId ~= nil then
        parentId  = DungeonAreaM.getParentId(dungeonId);
    end

    -- 设置顶部和底部背景
    -- 如果没有配置上下底图标，默认使用关卡编号
    local topBottomIcon = DungeonAreaM.query(parentId, "top_bottom_icon");
    if topBottomIcon == "" or topBottomIcon == nil then
        topBottomIcon = parentId;
    end

    local path = "images/ui/level/cover/";
    if parentId ~= nil then
        local topBgPath = path .. "top/" .. topBottomIcon .. ".png";
        local bottomBgPath = path .. "bottom/" .. topBottomIcon .. ".png";
        topBg:loadTexture(topBgPath);
        bottomBg:loadTexture(bottomBgPath);
    else
        topBg:setVisible(false);
        bottomBg:setVisible(false);
    end

    -- 隐藏group1
    local group1 = findChildByName(node, "CT/group1");
    group1:setVisible(false);

    -- BT部分
    -- 载入文字资源
    local goldTitle = findChildByName(node,"BT/gold_node/left/gold_title");
    local expTitle = findChildByName(node,"BT/exp_node/left/exp_title");
    local expProgressTitle = findChildByName(node,"BT/exp_progress_node/left/exp_progress_title");

    TextStyleM.setTextStyle(goldTitle, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BEIGE, true);
    TextStyleM.setTextStyle(expTitle, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BEIGE, true);
    TextStyleM.setTextStyle(expProgressTitle, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BEIGE, true);
    goldTitle:setString(getLocStr("get_gold_coin"));
    expTitle:setString(getLocStr("get_exp"));
    expProgressTitle:setString(getLocStr("exp_progress"));

    -- 总评分
    local titleSumLabel = findChildByName(self.node, "BT/total_score_node/title_sum");
    local scoreSumLabel = findChildByName(self.node, "BT/total_score_node/score_sum");

    TextStyleM.setTextStyle(titleSumLabel, TextStyleM.TEXT_SIZE_LARGE, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, kerning);
    TextStyleM.setTextStyle(scoreSumLabel, TextStyleM.TEXT_SIZE_LARGE, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true);
    titleSumLabel:setString(string.format(getLocStr("get_scores") .. "--"));
    titleSumLabel:setAnchorPoint(cc.p(0.5, 0));
    scoreSumLabel:setVisible(false);

    -- 先设置为0
    scoreSumLabel:setString("0");

    -- 先显示老的进度
    local loadingBar = findChildByName(self.node, "BT/exp_progress_node/right/progress_bg/loading_bar");
    local percent = self.oldExp / self.oldMaxExp * 100;
    loadingBar:setPercent(percent);

    -- 进度条
    self.playingLevelUpEffect = false;
    self.waitUserClick = false;
end

-- 开始动画
function UIMopUp:start()
    self:gotoState(STAT_STATE_TITLE_ANIMA);
end

-- 状态处理
function UIMopUp:gotoState(state)
    self.state = state;
    accelarateFactor = 1;
    self.isWaiting = false;

    local stateTables =
        {
            [STAT_STATE_TITLE_ANIMA] = UIMopUp.doBackgroudAnimation,
            [STAT_STATE_SCORE_ANIM] = UIMopUp.doScoreAnimation,
            [STAT_STATE_GROUP_ANIM] = UIMopUp.doGroupAnimation,
            [STAT_STATE_END] = function() end,
        };

    stateTables[self.state](self);

    if state == STAT_STATE_END then
        -- 重新显示panel
        local panel = findChildByName(self.node, "CT/panel/items");
        panel:setVisible(true);
        panel:setTouchEnabled(true);
        if self.ct ~= nil then
            removeLevelUpEffect(self.ct);
        end
    end
end

-- 背景动画
function UIMopUp:doBackgroudAnimation()
    -- 背景圆圈滚动
    local ctBg = findChildByName(self.node, "CT/ct_bg");
    ctBg:setScale(0.3);
    local scaleUp = cc.ScaleTo:create(0.5, 1.0);
    local callback = cc.CallFunc:create(function ()
        local rotateForever = cc.RepeatForever:create(cc.RotateBy:create(30, 360));
        ctBg:runAction(rotateForever);
    end);

    ctBg:runAction(cc.Sequence:create(scaleUp, callback));

    local function callback()
        -- 开始第一组评分动画
        self:gotoState(STAT_STATE_SCORE_ANIM);
    end

    self:titleAnimation(callback);
end

-- 标题动画
function UIMopUp:titleAnimation(callback)
    -- 标题先放大后缩小再放大
    local titleNode = findChildByName(self.node, "TOP/title_node");
    titleNode:setScale(1.5);

    local scaleDown = cc.ScaleTo:create(0.5, 0.9);
    local scaleUp = cc.ScaleTo:create(0.5, 1.0);
    local gotoNextState = cc.CallFunc:create(function ()
        if callback ~= nil then
            callback();
        end
    end);

    titleNode:runAction(cc.Sequence:create(scaleDown, scaleUp, gotoNextState));
end

-- 注册点击事件
function UIMopUp:registerTouchEvent()
    -- 点击背景快速结算本页，再次点击进入下一个结算
    local bg = findChildByName(self.node, "black_bg");
    bg:addTouchEventListener(function(sender, ev)
        if ev == ccui.TouchEventType.ended then
            self:skipHandler();
        end
    end);

    -- 返回按钮
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            self:closeWindow();
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 分享按钮
    local btnShare = findChildByName(self.node, "BT/btn_share");
    TextStyleM.setTextStyle(btnShare, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnShare:setTitleText(getLocStr("share"));
    -- 此界面不显示
    btnShare:setVisible(false);
end

function UIMopUp:closeWindow()
    -- 关闭界面的时候再尝试触发
    self:triggerSlimeEvent();

    UIMgr.getCurrentScene():removeFormByName("UIMopUp");

    UIMgr.tryClearUnusedTextures();
    EventMgr.fire(event.USER_EXP_UP);
end

-- 触发了史莱姆事件
function UIMopUp:triggerSlimeEvent()
    local args = self.args;
    if type(args) ~= "table"
        or SlimeEventM.query(args.eventId, "rule") ~= "spring_mop_up" then
        return;
    end

    local msgList = args.msgList;
    local endEffect = args.endEffect;

    require "game/ui/form/hero/UIHeroSpeak"
    local uiForm = UIHeroSpeak.create(self, args.heroId, msgList, "B_FLY_IN", "B_FLY_OUT", nil, endEffect, args);
    UIMgr.getCurrentScene():addForm(uiForm);
end

-- 快速略过处理
function UIMopUp:skipHandler()
    if self.isDoingExpAnimation and not self.waitUserClick then
        -- 正在播放进度条动画
        return;
    end

    if not self.isDoingExpAnimation then
        if self.flog then
            self:showScoreRightNow();
        end
        if self.itemsflog then
            local args = self.bonus;
            local items = self:initArgs(args)
            self:showItemsRightNow(items);
        end
    end

    if self.playingLevelUpEffect then
        -- 正在播放动画
        local function doneEffect()
            self.playingLevelUpEffect = false;
            self.waitUserClick = true;
        end
        -- 略过动画
        playLevelUpEffect(self.ct, self.oldLevel, doneEffect, true);
    elseif self.waitUserClick then
        -- 播完动画了
        self.waitUserClick = false;
    end
end

-- 等待下一步操作
function UIMopUp:waitingForNextStep()
    self.isWaiting = true;
end

-- 注册事件处理回调函数
function UIMopUp:registerEventCallback()
    EventMgr.register("UIMopUp", event.SLIME_TALK, function(args)
        self.args = args;
    end);

    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            cclog("UIMopUp 界面析构清理");
            EventMgr.removeAll("UIMopUp");
            if UIDungeonMgr:getCurLevel() ~= nil then
                UIDungeonMgr:getCurLevel():hideTop();
            end

            local uiSubAreaList = UIMgr.getCurrentScene():getFormByName("UISubAreaList");
            local uiActivityDungeon = UIMgr.getCurrentScene():getFormByName("UIActivityDungeon");
            if uiSubAreaList then
                uiSubAreaList:setVisible(true);
            elseif uiActivityDungeon then
                uiActivityDungeon:setVisible(true);
            end
        elseif ev == "enter" then
            local uiSubAreaList = UIMgr.getCurrentScene():getFormByName("UISubAreaList");
            local uiActivityDungeon = UIMgr.getCurrentScene():getFormByName("UIActivityDungeon");
            if uiSubAreaList then
                uiSubAreaList:setVisible(false);
            elseif uiActivityDungeon then
                uiActivityDungeon:setVisible(true);
            end
        end
    end);
end

function UIMopUp:init(args)
    -- 总行数
    local node = self.node;
    local bonusList = args["bonus"];

    local name;
    local amount;
    self.goldNum = 0;
    self.expNum = 0;
    for _, arr in pairs(bonusList) do

        if arr[1] == 2 then
            -- 属性奖励
            name = FieldsM.getFieldName(arr[2]);
            amount = arr[3];
            local goldName = FieldsM.getFieldName("money");
            local expName = FieldsM.getFieldName("exp");
            if(goldName == name) then
                self.goldNum = amount;
            elseif (expName == name) then
                 self.expNum = amount;
            end
        end
    end

    -- 经验/金钱
    local nodeNames = { "gold_node", "exp_node", "exp_progress_node" };
    for i = 1, #nodeNames do
        local left = findChildByName(self.node, "BT/"..nodeNames[i].."/left");
        left:setPositionX(DESIGN_WIDTH);
        local right = findChildByName(self.node, "BT/"..nodeNames[i].."/right");
        right:setPositionX(DESIGN_WIDTH);
    end

    -- 总积分
    local totalScoreNode = findChildByName(self.node, "BT/total_score_node");
    totalScoreNode:setPositionX(DESIGN_WIDTH);
end

-- 经验和金币动画
function UIMopUp:doScoreAnimation()
    local nodeNames = { "gold_node", "exp_node", "exp_progress_node" };

    -- 下面三行从左右分别飞入
    self.flog = true;
    local function next()
       self:scrollAddNum();
    end
    local callback = cc.CallFunc:create(function ()
        local i = 1;
        local delay = 0.2;
        local function btflyIn()
            local left = findChildByName(self.node, "BT/"..nodeNames[i].."/left");
            local right = findChildByName(self.node, "BT/"..nodeNames[i].."/right");
            local move1 = cc.MoveTo:create(textDuration, cc.p(0, left:getPositionY()));
            local move2 = cc.MoveTo:create(textDuration, cc.p(0, left:getPositionY()));

            left:runAction(move1);
            right:runAction(move2);

            i = i + 1;
            if i <= 3 then
                performWithDelay(self, btflyIn, delay);
            else
                performWithDelay(self, next, 1.1);
            end

            -- 播放飞入音效
            AudioM.playFx("stat_fly_in");
        end

        btflyIn();
    end);

    -- 总积分先飞入
    local totalScoreNode = findChildByName(self.node, "BT/total_score_node");
    local move = cc.MoveTo:create(textDuration, cc.p(0, totalScoreNode:getPositionY()));
    totalScoreNode:runAction(cc.Sequence:create(move, callback));
end

-- panel最初位置
local panelY;

-- 物品飞入
function UIMopUp:itemsFlyIn(items, callback)
    local group1 = findChildByName(self.node, "CT/group1");
    group1:setVisible(false);

    local panel = findChildByName(self.node, "CT/panel/items");
    panel:removeAllChildren();
    panelY = panel:getPosition();

    if self.itemFlyFinish then
        self:showItemsRightNow(items);
        return;
    end

    -- 飞入物品，不可拖动
    panel:setTouchEnabled(false);

    self.itemFlyFinish = false;

    if #items == 0 then
        if callback ~= nil then
            self.itemFlyFinish = true;
            callback();
        end
        return;
    end

    local itemWidth = 140;
    local leftMargin = 25;
    local hGap = 8.5;
    local vGap = 0;

    -- 设置容易高度
    local addLine = math.ceil(#items / 4) - 3;
    if addLine < 0 then
        addLine = 0;
    end

    -- 初始化位置
    for i = 1, #items do
        local item = items[i];
        local y = 420 - (math.floor((i-1) / 4) - addLine) * (itemWidth+vGap) - (itemWidth/2+vGap);
        panel:addChild(item);
        item:setPosition(cc.p(900, y));
    end

    if addLine > 0 then
        local totalHeight = 410 + (itemWidth+vGap) * addLine;
        panel:setInnerContainerSize(cc.size(panel:getInnerContainerSize().width, totalHeight));
        panel:scrollToTop(0.01, true);
    end

    local flyIn;
    local i = 1;
    local delayCount = 1;
    local capacity = 12;
    local alreadyAddLine = 1;

    -- 整个panel往上挪
    local function movePanelUp()
        local moveTo = cc.MoveTo:create(0.25 / accelarateFactor, cc.p(panel:getPositionX(), panel:getPositionY() + (itemWidth+vGap)));
        local callback = cc.CallFunc:create(function()
            capacity = capacity + 4;
            delayCount = 1;
            -- 继续飞入其他的item
            flyIn();
        end);

        local delay = cc.DelayTime:create(0.25);
        local totalHeight = panel:getInnerContainerSize().height;
        -- 计算上移的百分比
        local percent = alreadyAddLine / addLine * 100;
        -- 增加已经上移的次数
        alreadyAddLine = alreadyAddLine + 1;
        panel:scrollToPercentVertical(percent, 0.25, true);
        self:runAction(cc.Sequence:create(delay, callback));
    end

    local count = 0;

    -- 依次飞入
    flyIn = function()
        if i > capacity then
            -- 超过可显示个数，暂停，等panel上移后继续
            return;
        end

        if i > #items then
            return;
        end

        if self.itemsShowNow then
            return;
        end

        -- 物品飞入速度
        local speed = 2050 * accelarateFactor;

        local item = items[i];
        local delay = cc.DelayTime:create(delayCount * 0.1 / accelarateFactor);
        local x = leftMargin + itemWidth/2 + ((i-1)%4)*(itemWidth+hGap);
        local moveTo = cc.MoveTo:create((900-x)/speed, cc.p(x, item:getPositionY()));
        local callback = cc.CallFunc:create(function()
            count = count + 1;
            if count >= 12 and (count % 4) == 0 then
                if count ~= #items then
                    movePanelUp();
                end
            end

            if count >= #items then
                -- 播放完成
                self.itemFlyFinish = true;
                -- 可以拖动
                panel:setTouchEnabled(true);
                self:waitingForNextStep();
                if callback ~= nil then
                    callback();
                end
            end
        end);

        item:runAction(cc.Sequence:create(delay, moveTo, callback));

        -- 播放飞入音效
        AudioM.playFx("stat_fly_in");

        i = i + 1;
        delayCount = delayCount + 1;
        performWithDelay(self, flyIn, 0.1 / accelarateFactor);
    end

    flyIn();
end

-- 获得物品奖励
function UIMopUp:initArgs(args)
    -- 总行数
    local node = self.node;
    local panel = findChildByName(node, "CT/panel/items");
    local bonusList = args["bonus"];
    local item = cc.CSLoader:createNode("layout/combat_stat/CombatStatItem.csb");
    local widget = replaceNodeWithWidget(item);

    local j = 0;
    local items = {};

    if #bonusList <= 0 then
        return items;
    end

    local function sortItem(arr1, arr2)
        if arr1[2] < arr2[2] then
            return true;
        end
        return false;
    end

    local bonusItems = {};

    for _, arr in pairs(bonusList) do
        if arr[1] == 1 then
            table.insert(bonusItems, arr);
        end
    end

    -- 排序
    table.sort(bonusItems, sortItem);

    for _, arr in pairs(bonusItems) do

        if arr[1] == 1 then

            j = j + 1;
            local child = widget:clone();
            child:setName("item" .. j);

            -- 获取物品图标
            local iconIndex = ItemM.query(arr[2], "icon");
            local icon = child:getChildByName("icon");
            icon:loadTexture(getItemIconPath(iconIndex));

            -- 物品奖励
            local amount = arr[3];

            -- 数量
            local num  = child:getChildByName("num");
            TextStyleM.setTextStyle(num, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
            num:setString(tostring(amount));
            num:setFontSize(TextStyleM.TEXT_SIZE_SMALL);

            -- 星星
            local star = child:getChildByName("star");
            local rank = ItemM.query(arr[2], "rank");

            local tStar = createStarLayer(rank, "images/ui/symbol/star_little.png", "center", -0.7);
            if tStar ~= nil then
                star:addChild(tStar);
            end

            -- 点击处理
            local bg = findChildByName(child, "bg");
            bg:addTouchEventListener(function(sender, eventType)
                if eventType == ccui.TouchEventType.ended then
                    AudioM.playFx("workshop_material");
                    -- 显示道具详细信息
                    local groupList = {24,};
                    local itemGroup = ItemM.query(arr[2], "group")
                    if table.indexOf(groupList, itemGroup) ~= -1 then
                        -- 特殊物品
                        local uiPropertyInfo = UIPropertyInfo.create(arr[2]);
                        UIMgr.getCurrentScene():addForm(uiPropertyInfo);
                    else
                        local uiItemDesc = UIItemDesc.create(arr[2]);
                        UIMgr:getCurrentScene():addForm(uiItemDesc);
                    end
                end
            end);

            table.insert(items, child);
        end
    end
    -- 可能还有钻石会出现在扫荡项
    for _, arr in pairs(bonusList) do
        if arr[1] == 2 and arr[2] == "gem" then
            table.insert(bonusItems, arr);
            j = j + 1;
            local child = widget:clone();
            child:setName("item" .. j);

            -- 获取物品图标
            local iconIndex = FieldsM.query(arr[2], "icon");
            local icon = child:getChildByName("icon");
            icon:loadTexture(getLargeAttribIconPath(iconIndex));

            -- 物品奖励
            local amount = arr[3];

            -- 数量
            local num  = child:getChildByName("num");
            TextStyleM.setTextStyle(num, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
            num:setString(tostring(amount));
            num:setFontSize(TextStyleM.TEXT_SIZE_SMALL);
            table.insert(items, child);
        end
    end



    return items;
end

-- 立刻显示物品
function UIMopUp:showItemsRightNow(items)
    -- 隐藏
    local group1 = findChildByName(self.node, "CT/group1");
    group1:setVisible(false);
    self.itemsShowNow = true;
    -- self:stopAllActions();

    -- 停止当前所有动作, 直接到目标位置
    local panel = findChildByName(self.node, "CT/panel/items");
    local children = panel:getChildren();
    local len = table.getn(children)

    -- 重置panel位置
    if panelY ~= nil then
        panel:setPosition(panel:getPositionX(), panelY);
        panel:setTouchEnabled(false);
    end

    -- 飞入物品，不可拖动
    panel:setTouchEnabled(false);

    for i = 1, len do
        local child = children[i];
        child:stopAllActions();
    end
    panel:removeAllChildren();

    local itemWidth = 140;
    local leftMargin = 25;
    local hGap = 8.5;
    local vGap = 0;

    local num = #items;

    -- 设置容器高度
    local addLine = math.ceil(#items / 4) - 3;

    if addLine < 0 then
        addLine = 0;
    end

    if addLine > 0 then
        local totalHeight = 410 + (itemWidth+vGap) * addLine;
        panel:setInnerContainerSize(cc.size(panel:getInnerContainerSize().width, totalHeight));
        panel:scrollToTop(0.01, true);
    end

    -- 设置物品位置
    for i = 1, num do
        local item = items[i];
        local x = leftMargin + itemWidth/2 + ((i-1)%4)*(itemWidth+hGap);
        local y = 420 - (math.floor((i-1) / 4) - addLine) * (itemWidth+vGap) - (itemWidth/2+vGap);
        item:setPosition(x, y);
        panel:addChild(item);
    end

    -- 容器直接置到最底
    panel:jumpToBottom();

    panel:setTouchEnabled(true);

    self.itemFlyFinish = true;

    self:doExpAnimation();

    self:waitingForNextStep();
end

-- 计算积分与金币经验
function UIMopUp:scrollAddNum()
    -- 金币滚动
    local curMoney = self.goldNum;
    local goldAddLabel = findChildByName(self.node, "BT/gold_node/right/gold_value");
    TextStyleM.setTextStyle(goldAddLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BEIGE);
    scoreScrolling(goldAddLabel, curMoney, nil, 50);

    -- 经验滚动
    local addExp = self.expNum;
    local expAddLabel = findChildByName(self.node, "BT/exp_node/right/exp_value");
    TextStyleM.setTextStyle(expAddLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BEIGE);
    scoreScrolling(expAddLabel, addExp, nil, 50);

    -- 播放数值滚动音效
    AudioM.playFx("stat_scrolling");
    self:gotoState(STAT_STATE_GROUP_ANIM);
end

-- 物品飞入
function UIMopUp:doGroupAnimation()
    local args = self.bonus;
    local items = self:initArgs(args)
    self.flog = false;
    self.itemsflog = true;
    local function callback()
        self:doExpAnimation();
    end
    self:itemsFlyIn(items,callback);
end

-- 属性加成立即显示
function UIMopUp:showScoreRightNow()
    if self.showScoreDone then
        self.itemsflog = true;
        return;
    end

    self:stopAllActions();

    local nodeNames = { "gold_node", "exp_node", "exp_progress_node" };
    for i = 1, 3 do
        local left = findChildByName(self.node, "BT/"..nodeNames[i].."/left");
        left:stopAllActions();
        left:setPositionX(0);

        local right = findChildByName(self.node, "BT/"..nodeNames[i].."/right");
        right:stopAllActions();
        right:setPositionX(0);
    end
    local goldAddLabel = findChildByName(self.node, "BT/gold_node/right/gold_value");
    TextStyleM.setTextStyle(goldAddLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BEIGE);
    goldAddLabel:setString(tostring(self.goldNum));

    local expAddLabel = findChildByName(self.node, "BT/exp_node/right/exp_value");
    TextStyleM.setTextStyle(expAddLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BEIGE)
    expAddLabel:setString(tostring(self.expNum));
    self.itemsflog = true;
    self.showScoreDone = true;

    -- 自动进入下一个动画
    local function autoNext()
        self:doGroupAnimation();
    end
    performWithDelay(self, autoNext, 0.1);
end

-- 经验跳动的动画
function UIMopUp:doExpAnimation()
    self.itemsflog = false;
    self.isLastAnimation = true;
    local panel = findChildByName(self.node, "CT/panel/items");

    if self.isDoingExpAnimation then
        return;
    end

    self.isDoingExpAnimation = true;

    -- 经验条动画
    local loadingBar = findChildByName(self.node, "BT/exp_progress_node/right/progress_bg/loading_bar");

    local incCount = 50;
    local incDelta = self.expNum / incCount;

    local count = 0;
    local function increaseExpBar()
        if self.playingLevelUpEffect or self.waitUserClick then
            performWithDelay(self, increaseExpBar, 0.01);
            return;
        end
        local nextDelta = incDelta;
        if self.oldExp + incDelta >= self.oldMaxExp then
            nextDelta = incDelta - (self.oldMaxExp - self.oldExp);
            -- 升级动画，需要隐藏panel
            panel:setPosition(cc.p(0, 0));
            panel:setVisible(false);
            panel:setTouchEnabled(false);

            -- 升级需要等待玩家确认
            self.waitUserClick = true;

            self.oldExp = 0;
            self.oldLevel = self.oldLevel + 1;
            self.oldMaxExp = UserM.queryWorldTree(self.oldLevel, "exp");

            -- 显示升级动画
            self.playingLevelUpEffect = true;
            self.ct = self.node:getChildByName("CT");
            local function doneEffect()
                self.playingLevelUpEffect = false;
                self.waitUserClick = true;
            end
            loadingBar:setPercent(100);
            playLevelUpEffect(self.ct, self.oldLevel, doneEffect, false);
        end

        self.oldExp = self.oldExp + nextDelta;
        if not self.playingLevelUpEffect then
            local percent = self.oldExp / self.oldMaxExp * 100;
            loadingBar:setPercent(percent);
        end

        count = count + 1;
        if count >= incCount and not self.playingLevelUpEffect then
            self.isWaiting = true;
            self:waitingForNextStep();
            self:gotoState(STAT_STATE_END);
        else
            performWithDelay(self, increaseExpBar, 0.01);
        end
    end

    performWithDelay(self, increaseExpBar, 1);
end
